package com.hifar.sso.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hifar.abi.base.utils.AuthCfgUtils;
import com.hifar.fw.json.JsonUtils;
import com.hifar.fw.utils.consts.SysConsts;
import com.hifar.fw.utils.jwt.JwtUtils;
import com.hifar.fw.utils.lang.StringUtils;
import com.hifar.plat.baseModal.secretstrategy.pojo.SysPersonsecretDatasecretRelation;
import com.hifar.plat.baseModal.secretstrategy.service.ISysPersonsecretDatasecretRelationService;
import com.hifar.plat.dept.pojo.BaseOrgDeptPlat;
import com.hifar.plat.dept.service.IBaseOrgDeptPlatService;
import com.hifar.plat.user.pojo.BaseOrgUserPlat;
import com.hifar.plat.user.service.IBaseOrgUserService;
import com.hifar.sso.model.CallbackResponse;
import com.hifar.sys.BusiResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhuWeiWei
 * @description TODO
 * @date 2025/10/12 18:09
 */
@RestController
@RequestMapping("/api/busi/key_sso")
@CrossOrigin(origins = "*")
public class KeySSOLoginController {
    @Value("${sys-config.env:SM}")
    private String sysEnv;

    @Autowired
    private IBaseOrgUserService baseOrgUserService;
    @Autowired
    private ISysPersonsecretDatasecretRelationService sysPersonsecretDatasecretRelationService;
    @Autowired
    private IBaseOrgDeptPlatService baseOrgDeptPlatService;

    private static final Logger logger = LoggerFactory.getLogger(SSOAuthController.class);

    @PostMapping("/api/login")
    public BusiResponse<CallbackResponse> callback(HttpServletRequest request) {
        StringBuilder body = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = request.getReader();
            String line;
            while ((line = reader.readLine()) != null) {
                body.append(line);
            }
        } catch (IOException var6) {
            var6.printStackTrace();
        }
        String loginParams = body.toString();

        String[] paramsArr = loginParams.split("&");

        Map<String, String> paramMap = new HashMap<>();
        for (String param : paramsArr) {
            String[] paramValueArr = param.split("=");
            paramMap.put(paramValueArr[0], paramValueArr.length > 1 ? paramValueArr[1] : null);
        }

        logger.info("SSO回调请求: {}", loginParams);

        String username = StringUtils.trimNull(paramMap.get("username"));
        String password = StringUtils.trimNull(paramMap.get("password"));
        QueryWrapper<BaseOrgUserPlat> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lambda()
                .eq(BaseOrgUserPlat::getUserCode, username)
                .ne(BaseOrgUserPlat::getStatus, SysConsts.LOGIC_DELETE);
        List<BaseOrgUserPlat> hisUserList = baseOrgUserService.list(userQueryWrapper);
        BaseOrgUserPlat baseOrgUserPlat = hisUserList.isEmpty() ? null : hisUserList.get(0);
        Assert.notNull(baseOrgUserPlat, "用户不存在!");
        String pwd = baseOrgUserPlat.getPwd();
        Integer salt = baseOrgUserPlat.getSalt();
        String enPwd = AuthCfgUtils.encryptPwd(password + salt);
        Assert.isTrue(Objects.equals(pwd,enPwd), "密码不正确!");

        String personKey = StringUtils.trimNull(baseOrgUserPlat.getSecretLevel());
        List<SysPersonsecretDatasecretRelation> dataSecretRelationList = sysPersonsecretDatasecretRelationService.lambdaQuery()
                .eq(SysPersonsecretDatasecretRelation::getPersonSecretKey, personKey)
                .eq(SysPersonsecretDatasecretRelation::getDelFlag, 0)
                .list();
        Set<String> dataSecretLevels = dataSecretRelationList.stream()
                .map(item -> StringUtils.trimNull(item.getDataSecretKey()))
                .collect(Collectors.toSet());

        long tm = System.currentTimeMillis();
        Map<String, Object> sessionMap = new HashMap<>();
        long duration = AuthCfgUtils.getSessionTimeout();
        sessionMap.put("tenantId", baseOrgUserPlat.getTenantId());
        sessionMap.put("userId", baseOrgUserPlat.getId());
        sessionMap.put("userCode", baseOrgUserPlat.getUserCode());
        sessionMap.put("idName", baseOrgUserPlat.getIdName());
        sessionMap.put("mobile", baseOrgUserPlat.getMobile());
        sessionMap.put("iat", tm);
        sessionMap.put("exp", tm + duration);
        sessionMap.put("secretLevel", baseOrgUserPlat.getSecretLevel());
        sessionMap.put("dataSecretLevel", String.join(",", dataSecretLevels));
        sessionMap.put("userType", baseOrgUserPlat.getUserType());
        sessionMap.put("deptId", baseOrgUserPlat.getDeptId());


        String sessionStr = JsonUtils.toJson(sessionMap);
        String jwtToken = JwtUtils.createHS256Token(sessionStr, AuthCfgUtils.getTokenKey());

        String deptId = baseOrgUserPlat.getDeptId();
        BaseOrgDeptPlat baseOrgDeptPlat = new BaseOrgDeptPlat();
        if (StringUtils.isNotBlank(deptId)) {
            baseOrgDeptPlat = baseOrgDeptPlatService.getById(deptId);
        }
        CallbackResponse callbackResponse = new CallbackResponse();
        callbackResponse.setToken(jwtToken);
        callbackResponse.setUserInfo(baseOrgUserPlat);
        callbackResponse.setDeptInfo(baseOrgDeptPlat);
        Map<String, Object> ext = new HashMap<>(2);

        // 平台登陆通过
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken(username, "123123");
            // 执行登陆操作
            subject.login(token);
        }
        if (null != subject.getSession()) {
            String sessionId = (String) subject.getSession().getId();
            ext.put("sessionId", sessionId);
        }
        BusiResponse response = new BusiResponse();
        ext.put("systemConfigEnv", sysEnv);
        response.setExt(ext);
        response.setData(callbackResponse);
        return response;

    }
}
